package com.aotain.oframework.util.io;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Util class for File System housekeep purposes
 * @author Jacob.cw.Zhang@gmail.com
 */
public class FilesRemover {

	private static Logger logger = LoggerFactory.getLogger(FilesRemover.class);
	public static final String TYPE_RECURSIVE = "R";
	public static final String TYPE_NON_RECURSIVE = "N";
	
	/**
	 * Remove file based upon retention period
	 * @param purgeDir Purge directory
	 * @param currDate Calculated date from
	 * @param retentionPeriod Retention period
	 * @param dirPurgeType Directory Purge type
	 * @throws IOException
	 */
	public static void purgeFiles(File purgeDir, Date currDate, int retentionPeriod, String dirPurgeType) throws IOException {
		logger.info("directory is :" + purgeDir);
		File[] files = purgeDir.listFiles();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(currDate);
		calendar.add(Calendar.DATE, -retentionPeriod);
		for (int i = 0; i < files.length; i++) {
			Date lastModifiedDate = new Date(files[i].lastModified());
			Calendar lastModifiedCal = Calendar.getInstance();
			lastModifiedCal.setTime(lastModifiedDate);
			if (files[i].isFile()) {
				if (calendar.after(lastModifiedCal)) {
					boolean delF = FileUtils.deleteQuietly(files[i]);
					if (!delF) {
						FileUtils.forceDeleteOnExit(files[i]);
					}
				}
			} else if (files[i].isDirectory() && TYPE_RECURSIVE.equals(dirPurgeType)) {
				File subFolder = new File(files[i].toString());
				purgeFiles(subFolder, currDate, retentionPeriod, dirPurgeType);
			}
		}
	}
	
	public static void removeFile(File file) {
		if (file == null) {
			throw new IllegalArgumentException("Passed-in file argument is null");
		} else {
			List<File> fileList = new ArrayList<File>(5);
			fileList.add(file);
			removeFiles(fileList, file);
		}
	}

	public static void removeFiles(List<File> fileList, File houseKeepDir) {
		long start = System.currentTimeMillis();
		int count = 0;
		try {
			if (fileList == null || fileList.isEmpty()) {
				return;
			} else {
				count = fileList.size();
			}
			int size = fileList.size();
			File file ;
			StringBuffer buffer;
			String filePath;
			for (int i = 0; i < size; i++) {
				file = fileList.get(i);
				boolean isDirectory = file.isDirectory();
				filePath = file.getAbsolutePath();
				boolean hasDeleted = FileUtils.deleteQuietly(file);
				if (hasDeleted) {
					buffer = new StringBuffer();
					if (isDirectory) {
						buffer.append("Directory housekeep including its sub-contents under dir,");
					} else {
						buffer.append("File housekeep, ");
					}
					buffer.append(filePath);
				} else {
					try {
						FileUtils.forceDeleteOnExit(file);
						buffer = new StringBuffer();
						if (isDirectory) {
							buffer.append("Directory housekeep including its sub-contents under dir,");
						} else {
							buffer.append("File housekeep, ");
						}
						buffer.append(filePath);
					} catch (Exception e) {
						logger.error("Exception caused while housekeeping file," + file, e);
					}
				}
			}
		} finally {
			if(count>0){
				long etime = System.currentTimeMillis() - start;
				StringBuffer buf = new StringBuffer();
				buf.append("Time used ");
				if (houseKeepDir != null) {
					buf.append("in housekeep directory, ");
					buf.append(houseKeepDir);
					buf.append(", ");
				}
				buf.append("housekeep file object=");
				buf.append(count);
				buf.append(", etime-in-ms=");
				buf.append(etime);
				logger.info(buf.toString());
			}
		}
	}
	
	public static boolean removeFolder(File folder){
		if(folder.isDirectory()){
			return FileUtils.deleteQuietly(folder);
		}else{
			logger.warn("folder is not a directory");
		}
		return false;
	}
	
}
